package com.rmy.queue.service.impl;

import java.util.List;

import com.rmy.common.annotation.DataScope;
import com.rmy.common.core.domain.AjaxResult;
import com.rmy.common.core.lang.IdGenerator;
import com.rmy.common.core.text.Convert;
import com.rmy.common.utils.DateUtils;
import com.rmy.common.utils.SecurityUtils;
import com.rmy.common.utils.StringUtils;
import com.rmy.queue.api.domain.UploadCallNumberReq;
import com.rmy.queue.api.domain.UploadTakeNumberReq;
import com.rmy.queue.common.ErrorTipsConst;
import com.rmy.queue.common.QueueConst;
import com.rmy.queue.domain.*;
import com.rmy.queue.mapper.QmsWindowInfoMapper;
import com.rmy.queue.service.IQmsBusinessConfigService;
import com.rmy.queue.service.IQmsCompConfigService;
import com.rmy.queue.service.IQmsWindowInfoService;
import org.apache.catalina.security.SecurityUtil;
import org.apache.poi.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rmy.queue.mapper.QmsQueueListMapper;
import com.rmy.queue.service.IQmsQueueListService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 排队队列Service业务层处理
 *
 * @author rmy
 * @date 2022-09-29
 */
@Service
public class QmsQueueListServiceImpl implements IQmsQueueListService
{
    private Logger logger = LoggerFactory.getLogger(IQmsQueueListService.class);

    @Autowired
    private QmsQueueListMapper qmsQueueListMapper;

    @Autowired
    private IQmsBusinessConfigService qmsBusinessConfigService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private IQmsWindowInfoService qmsWindowInfoService;

    @Autowired
    private IQmsCompConfigService qmsCompConfigService;

    /**
     * 查询排队队列
     *
     * @param serialNo 排队队列主键
     * @return 排队队列
     */
    @Override
    public QmsQueueList selectQmsQueueListBySerialNo(String serialNo)
    {
        return qmsQueueListMapper.selectQmsQueueListBySerialNo(serialNo);
    }

    /**
     * 查询排队队列列表
     *
     * @param qmsQueueList 排队队列
     * @return 排队队列
     */
    @Override
    public List<QmsQueueList> selectQmsQueueListList(QmsQueueList qmsQueueList)
    {
        return qmsQueueListMapper.selectQmsQueueListList(qmsQueueList);
    }

    /**
     * 新增排队队列
     *
     * @param qmsQueueList 排队队列
     * @return 结果
     */
    @Override
    public int insertQmsQueueList(QmsQueueList qmsQueueList)
    {
        return qmsQueueListMapper.insertQmsQueueList(qmsQueueList);
    }

    /**
     * 修改排队队列
     *
     * @param qmsQueueList 排队队列
     * @return 结果
     */
    @Override
    public int updateQmsQueueList(QmsQueueList qmsQueueList)
    {
        return qmsQueueListMapper.updateQmsQueueList(qmsQueueList);
    }

    /**
     * 批量删除排队队列
     *
     * @param serialNos 需要删除的排队队列主键
     * @return 结果
     */
    @Override
    public int deleteQmsQueueListBySerialNos(String[] serialNos)
    {
        return qmsQueueListMapper.deleteQmsQueueListBySerialNos(serialNos);
    }

    /**
     * 删除排队队列信息
     *
     * @param serialNo 排队队列主键
     * @return 结果
     */
    @Override
    public int deleteQmsQueueListBySerialNo(String serialNo)
    {
        return qmsQueueListMapper.deleteQmsQueueListBySerialNo(serialNo);
    }

    @Override
    public int genQueueNumber(QmsQueueList qmsQueueList) {

        String strQueueNo = "0";
        // 1. 查询业务配置信息
        QmsBusinessConfig qmsBusinessConfig = qmsBusinessConfigService.selectQmsBusinessConfigById(qmsQueueList.getBusinessId());
        // 2. 查询上次的排队信息
        String strTmpQueueNo = qmsQueueListMapper.selectLastQueueInfo(qmsQueueList);
        if (!StringUtils.isEmpty(strTmpQueueNo)) {
            strQueueNo = strTmpQueueNo.substring(qmsBusinessConfig.getBusinessWord().length());
        }
        Long nQueueNo = Convert.toLong(strQueueNo);
        if (nQueueNo >= qmsBusinessConfig.getEndNo() || nQueueNo == 0) {
            nQueueNo = qmsBusinessConfig.getBeginNo();
        } else {
            nQueueNo++;
        }
        // 设置新的排队号码
        qmsQueueList.setQueueNo(qmsBusinessConfig.getBusinessWord() + String.format("%03d", nQueueNo));
        qmsQueueList.setSerialNo(idGenerator.nextIdStr());
        qmsQueueList.setBeginTime(DateUtils.getNowDate());
        // 已取号
        qmsQueueList.setStatus("1");

        return qmsQueueListMapper.insertQmsQueueList(qmsQueueList);
    }

    @Transactional(rollbackFor = Exception.class) // 注意回滚的异步问题
    @Override
    public synchronized String callQueueNo(QmsQueueList qmsQueueList) {
        // 1. 根据窗口号查询上次叫号信息
        QmsQueueList lastCallInfo = qmsQueueListMapper.selectLastCallInfo(qmsQueueList.getWindowId());
        if (lastCallInfo == null) {
            // 2-1.窗口第一次叫号 直接执行3
        } else {
            // 2-2.更次上次叫号结束时间及状态
            lastCallInfo.setEndTime(DateUtils.getNowDate());
            lastCallInfo.setStatus(QueueConst.QUEUE_STATUS.COMPLETE);
            qmsQueueListMapper.updateQmsQueueList(lastCallInfo);
        }
        // 3. 取下一号码
        QmsQueueList nextQueueInfo = getNextQueueNo(qmsQueueList);
        if (null == nextQueueInfo) {
            // 队列无号码可取
            return "-1";
        }
        // 4. 更新成叫号状态
        // 窗口ID
        nextQueueInfo.setWindowId(qmsQueueList.getWindowId());
        // 用户名称
        nextQueueInfo.setCallerId(qmsQueueList.getCallerId());
        nextQueueInfo.setStatus(QueueConst.QUEUE_STATUS.CALL_NUMBER);
        nextQueueInfo.setCallTime(DateUtils.getNowDate());
        qmsQueueListMapper.updateQmsQueueList(nextQueueInfo);

        // 5. 根据窗口查询绑定语音设备 并循环发送

        // 6. 根据窗口查询绑定窗口条屏 并循环发送

        // 7. 根据机构代码查询综合屏 并循环发送
        QmsCompConfig qmsCompConfig = new QmsCompConfig();
        qmsCompConfig.setOrgNo(qmsQueueList.getOrgNo());
        List<QmsCompConfig> qmsCompConfigList = qmsCompConfigService.selectQmsCompConfigList(qmsCompConfig);
        for (QmsCompConfig tmp : qmsCompConfigList) {
            // 调用SDK发送配置内容

        }
        return nextQueueInfo.getSerialNo();
    }

    @Override
    public QmsQueueList getNextQueueNo(QmsQueueList qmsQueueList) {
        // 1. 查询转移过来的号码
        List<QmsQueueList> transferQueueList = qmsQueueListMapper.selectTransferQueue(qmsQueueList);
        if (null != transferQueueList && transferQueueList.size() > 0) {
            // 2-1. 存在转移过来的号码
            return transferQueueList.get(0);
        } else {
            // 2-2. 查询预约的号码
            List<QmsQueueList> preQueueList = qmsQueueListMapper.selectPreQueue(qmsQueueList);
            if (null != preQueueList && preQueueList.size() > 0) {
                // 2-2-1. 存在预约排队信息
                return preQueueList.get(0);
            } else {
                // 2-2-2. 查询普通排队信息
                    List<QmsQueueList> commonQueueList = this.selectCommonQueue(qmsQueueList);
                if (null != commonQueueList && commonQueueList.size() > 0) {
                    return commonQueueList.get(0);
                }
            }
        }
        return null;
    }

    @Override
    public String callNumber(QmsQueueList qmsQueueList) throws Exception {
        return callQueueNo(qmsQueueList);
    }

    @Override
    @DataScope(deptAlias = "d")
    public List<QmsQueueList> selectCommonQueue(QmsQueueList qmsQueueList) {
        return qmsQueueListMapper.selectCommonQueue(qmsQueueList);
    }

    @Transactional(rollbackFor = Exception.class) // 注意回滚的异步问题
    @Override
    public synchronized QmsQueueList callQueueNoByBusiness(QmsQueueList qmsQueueList) {
        // 1. 根据窗口号查询上次叫号信息
        QmsQueueList lastCallInfo = qmsQueueListMapper.selectLastCallInfo(qmsQueueList.getWindowId());
        if (lastCallInfo == null) {
            // 2-1.窗口第一次叫号 直接执行3
        } else {
            // 2-2.更次上次叫号结束时间及状态
            lastCallInfo.setEndTime(DateUtils.getNowDate());
            lastCallInfo.setStatus(QueueConst.QUEUE_STATUS.COMPLETE);
            qmsQueueListMapper.updateQmsQueueList(lastCallInfo);
        }
        // 3. 取下一号码
        QmsQueueList nextQueueInfo = getNextQueueNo(qmsQueueList);
        if (null == nextQueueInfo) {
            // 队列无号码可取
            return null;
        }
        // 4. 更新成叫号状态
        // 窗口ID
        nextQueueInfo.setWindowId(qmsQueueList.getWindowId());
        // 用户名称
        nextQueueInfo.setCallerId(qmsQueueList.getCallerId());
        nextQueueInfo.setStatus(QueueConst.QUEUE_STATUS.CALL_NUMBER);
        nextQueueInfo.setCallTime(DateUtils.getNowDate());
        qmsQueueListMapper.updateQmsQueueList(nextQueueInfo);

        return nextQueueInfo;
    }

    @Override
    public QmsQueueList selectAvaliableReCall(QmsQueueList qmsQueueList) {
        List<QmsQueueList> qmsQueueLists = qmsQueueListMapper.selectAvaliableReCall(qmsQueueList);
        if (qmsQueueLists == null || qmsQueueLists.size() == 0) {
            return null;
        }
        return qmsQueueLists.get(0);
    }

    @Override
    public QmsQueueList selectQmsQueueByQueueNo(QmsQueueList qmsQueueList) {
        return qmsQueueListMapper.selectQmsQueueByQueueNo(qmsQueueList);
    }

    @Override
    public int updateQueueCompleteByWindowId(Long windowId) {
        int nRet = 1;
        // 1. 根据窗口号查询上次叫号信息
        QmsQueueList lastCallInfo = qmsQueueListMapper.selectLastCallInfo(windowId);
        if (lastCallInfo == null) {
            // 2-1.窗口第一次叫号 直接执行3
        } else {
            // 2-2.更次上次叫号结束时间及状态
            lastCallInfo.setEndTime(DateUtils.getNowDate());
            lastCallInfo.setStatus(QueueConst.QUEUE_STATUS.COMPLETE);
            nRet = qmsQueueListMapper.updateQmsQueueList(lastCallInfo);
        }

        return nRet;
    }

    @Override
    public QmsQueueList ignoreCurrentNumberByUuid(String windowUuid) throws Exception {
        QmsWindowInfo qmsWindowInfo = qmsWindowInfoService.checkWindowExistByUuid(windowUuid);
        QmsQueueList qmsQueueList = new QmsQueueList();
        qmsQueueList.setCallerId(SecurityUtils.getUsername());
        qmsQueueList.setOrgNo(Convert.toStr(SecurityUtils.getDeptId()));
        qmsQueueList.setWindowId(qmsWindowInfo.getId());

        QmsQueueList resQueue = this.selectAvaliableReCall(qmsQueueList);
        if (resQueue == null) {
            logger.warn("当前没有查到正在叫号的排队信息");
            throw new Exception("请先叫号，才能跳过！");
        }
        resQueue.setCallerId(SecurityUtils.getUsername());
        resQueue.setStatus(QueueConst.QUEUE_STATUS.IGNORE);
        resQueue.setEndTime(DateUtils.getNowDate());
        resQueue.setWindowId(qmsWindowInfo.getId());
        this.updateQmsQueueList(resQueue);
        return resQueue;
    }

    @Override
    public List<QmsQueueList> selectQueueListByOrgNo(String orgNo) {
        return qmsQueueListMapper.selectQueueListByOrgNo(orgNo);
    }

    @Override
    public List<QmsQueueList> selectCalledListByOrgNo(String orgNo) {
        return qmsQueueListMapper.selectCalledListByOrgNo(orgNo);
    }

    @Override
    public int uploadTakeNumberInfo(UploadTakeNumberReq uploadTakeNumberReq) {
        // 1. 校验当前机构下号码信息是否存在
        Assert.hasText(uploadTakeNumberReq.getQueueNo(), ErrorTipsConst.TIPS_QUEUE_NO_NULL);
        Assert.hasText(uploadTakeNumberReq.getOrgNo(), ErrorTipsConst.TIPS_ORG_NO_NULL);
        QmsQueueList qmsQueueList = new QmsQueueList();
        qmsQueueList.setQueueNo(uploadTakeNumberReq.getQueueNo());
        qmsQueueList.setOrgNo(uploadTakeNumberReq.getOrgNo());
        int nRet = qmsQueueListMapper.checkQueueNumberRepeat(qmsQueueList);
        Assert.isTrue(nRet < 1, ErrorTipsConst.TIPS_QUEUE_NO_EXIST);

        // 2. 根据业务名称查询业务配置表
        QmsBusinessConfig qmsBusinessConfig = new QmsBusinessConfig();
        qmsBusinessConfig.setBusinessName(uploadTakeNumberReq.getBusinessName());
        List<QmsBusinessConfig> qmsBusinessConfigList = qmsBusinessConfigService.selectQmsBusinessConfigList(qmsBusinessConfig);
        if (qmsBusinessConfigList.size() == 0) {
            // 新增业务配置
            qmsBusinessConfig.setBeginNo(1L);
            qmsBusinessConfig.setEndNo(999L);
            qmsBusinessConfig.setStatus("0");
            qmsBusinessConfig.setBusinessWord(uploadTakeNumberReq.getQueueNo().substring(0,1));
            qmsBusinessConfigService.insertQmsBusinessConfig(qmsBusinessConfig);
        } else {
            qmsBusinessConfig = qmsBusinessConfigList.get(0);
        }

        // 3. 推送到大堂经理PAD

        // 4. 新增取号信息
        qmsQueueList.setSerialNo(idGenerator.nextIdStr());
        qmsQueueList.setCertType(uploadTakeNumberReq.getCertType());
        qmsQueueList.setCardNo(uploadTakeNumberReq.getCardNo());
        qmsQueueList.setQmId(Convert.toLong(uploadTakeNumberReq.getDeviceId()));
        qmsQueueList.setBeginTime(DateUtils.getNowDate());
        qmsQueueList.setBusinessId(qmsBusinessConfig.getId());
        qmsQueueList.setStatus(QueueConst.QUEUE_STATUS.TAKE_NUMBER);
        return qmsQueueListMapper.insertQmsQueueList(qmsQueueList);
    }

    @Override
    public int uploadCallNumberInfo(UploadCallNumberReq uploadCallNumberReq) {
        // 1. 验证
        Assert.hasText(uploadCallNumberReq.getQueueNo(), ErrorTipsConst.TIPS_QUEUE_NO_NULL);
        Assert.hasText(uploadCallNumberReq.getOrgNo(), ErrorTipsConst.TIPS_ORG_NO_NULL);
        QmsQueueList qmsQueueList = new QmsQueueList();
        qmsQueueList.setQueueNo(uploadCallNumberReq.getQueueNo());
        qmsQueueList.setOrgNo(uploadCallNumberReq.getOrgNo());
        List<QmsQueueList> todayQueue = qmsQueueListMapper.selectTodayQueue(qmsQueueList);
        Assert.notEmpty(todayQueue, ErrorTipsConst.TIPS_QUEUE_NO_NOT_EXIST);

        // 2. 查询窗口是否存在 不存在新增
        QmsWindowInfo qmsWindowInfo = new QmsWindowInfo();
        qmsWindowInfo.setOrgNo(uploadCallNumberReq.getOrgNo());
        qmsWindowInfo.setWindowNumber(Convert.toLong(uploadCallNumberReq.getWindowNumber()));
        List<QmsWindowInfo> qmsWindowInfoList = qmsWindowInfoService.selectQmsWindowInfoList(qmsWindowInfo);
        if (qmsWindowInfoList.size() == 0){
            qmsWindowInfo.setUuid(idGenerator.nextIdStr());
            qmsWindowInfo.setCreateBy("sysinterface");
            qmsWindowInfo.setCreateTime(DateUtils.getNowDate());
            qmsWindowInfo.setWindowName(uploadCallNumberReq.getWindowNumber()+"号窗口");
            qmsWindowInfoService.insertQmsWindowInfo(qmsWindowInfo);
        } else {
            qmsWindowInfo = qmsWindowInfoList.get(0);
        }

        // 3. 查询上次叫号的信息
        QmsQueueList lastCallInfo = qmsQueueListMapper.selectLastCallInfo(qmsWindowInfo.getId());
        if (lastCallInfo == null) {
            // 3-1.窗口第一次叫号 直接执行3
        } else {
            // 3-2.更次上次叫号结束时间及状态
            lastCallInfo.setEndTime(DateUtils.getNowDate());
            lastCallInfo.setStatus(QueueConst.QUEUE_STATUS.COMPLETE);
            qmsQueueListMapper.updateQmsQueueList(lastCallInfo);
        }

        // 4. 查询当前窗口对应的登录人 TODO

        // 5. 推送客户到柜员助手


        // 6. 更新
        QmsQueueList updateObj = todayQueue.get(0);
        updateObj.setWindowId(qmsWindowInfo.getId());
        updateObj.setCallTime(DateUtils.getNowDate());
        updateObj.setStatus(QueueConst.QUEUE_STATUS.CALL_NUMBER);

        return qmsQueueListMapper.updateQmsQueueList(updateObj);
    }

}
